Standard.site landing page built in Next.js
at main 93 lines 3.2 kB view raw
1import { notFound } from 'next/navigation' 2import { Metadata } from 'next' 3import { readFile } from 'fs/promises' 4import { join } from 'path' 5import { getAllDocSlugs } from '@/app/data/docs-nav' 6import { getDocMarkdown } from '@/app/lib/mdx-to-markdown' 7import { DocsMarkdownProvider } from '@/app/components/docs/DocsMarkdownContext' 8 9// Map of slugs to their MDX content imports 10const docsContent: Record<string, () => Promise<{ default: React.ComponentType }>> = { 11 'introduction': () => import('@/content/docs/introduction.mdx'), 12 'quick-start': () => import('@/content/docs/quick-start.mdx'), 13 'permissions': () => import('@/content/docs/permissions.mdx'), 14 'verification': () => import('@/content/docs/verification.mdx'), 15 'lexicons/publication': () => import('@/content/docs/lexicons/publication.mdx'), 16 'lexicons/document': () => import('@/content/docs/lexicons/document.mdx'), 17 'lexicons/subscription': () => import('@/content/docs/lexicons/subscription.mdx'), 18 'lexicons/theme': () => import('@/content/docs/lexicons/theme.mdx'), 19 'implementations': () => import('@/content/docs/implementations.mdx'), 20 'faq': () => import('@/content/docs/faq.mdx'), 21} 22 23async function getFrontmatter(slugPath: string): Promise<{ title?: string; description?: string; ogImage?: string; atUri?: string }> { 24 const filePath = join(process.cwd(), 'content', 'docs', `${slugPath}.mdx`) 25 const raw = await readFile(filePath, 'utf-8') 26 27 const match = raw.match(/^---\n([\s\S]*?)\n---/) 28 if (!match) return {} 29 30 const frontmatter: Record<string, string> = {} 31 for (const line of match[1].split('\n')) { 32 const [key, ...rest] = line.split(':') 33 if (key && rest.length) { 34 frontmatter[key.trim()] = rest.join(':').trim().replace(/^["']|["']$/g, '') 35 } 36 } 37 38 return frontmatter 39} 40 41// Generate static params for all doc pages 42export function generateStaticParams() { 43 return getAllDocSlugs().map((slug) => ({ slug })) 44} 45 46export async function generateMetadata({ 47 params, 48}: { 49 params: Promise<{ slug: string[] }> 50}): Promise<Metadata> { 51 const { slug } = await params 52 const slugPath = slug.join('/') 53 54 if (!docsContent[slugPath]) return {} 55 56 const { title, description, ogImage } = await getFrontmatter(slugPath) 57 58 return { 59 title: title ? `${title} - Standard.site` : undefined, 60 description, 61 openGraph: { 62 title: title ? `${title} - Standard.site` : undefined, 63 description, 64 images: ogImage ? [`/media/${ogImage}`] : undefined, 65 }, 66 } 67} 68 69export default async function DocPage({ 70 params, 71}: { 72 params: Promise<{ slug: string[] }> 73}) { 74 const { slug } = await params 75 const slugPath = slug.join('/') 76 77 const loader = docsContent[slugPath] 78 if (!loader) { 79 notFound() 80 } 81 82 const [{ default: Content }, markdown, { atUri }] = await Promise.all([ 83 loader(), 84 getDocMarkdown(slugPath), 85 getFrontmatter(slugPath), 86 ]) 87 88 return ( 89 <DocsMarkdownProvider markdown={markdown} atUri={atUri}> 90 <Content /> 91 </DocsMarkdownProvider> 92 ) 93}